<template>
  <div class="index-container">
    <div class="title">购物车</div>
    <van-row type="flex" justify='justify="space-between' style="text-align: center; align-items: center">
      <van-col span="8">30天无忧退货</van-col>
      <van-col span="8">48小时快速退款</van-col>
      <van-col span="8">满88元免邮费</van-col>
    </van-row>
    <!-- 商品卡片内容 -->
    <van-row class="goods-card" v-for="item in cartIndexList" :key="item.id">
      <!-- 复选框666666666666666666666666666666 -->
      <!-- Change 事件一般作用于标签，可以监听input的value值，当它的value有变化时，在失去焦点后触发change事件。 -->
      <van-col span="2" type="flex">
        <van-checkbox v-model="item.checked" @change="onCheCkange(item)"></van-checkbox>
      </van-col>
      <!-- 图片 -->
      <van-col span="3"><img :src="item.picUrl" alt=""/></van-col>
      <!-- 描述 -->
      <van-col span="13">
        <!-- 商品标题 -->
        <van-row>{{ item.goodsName }}</van-row>
        <van-row>{{ item.specifications.join(' - ') }}</van-row>
        <!-- 价钱 -->
        <van-row> ￥{{ item.price }} </van-row>
      </van-col>
      <!-- 数量 -->
      <van-col span="6" style="text-align: center">
        <van-row v-if="!isedit" style="margin-top: 3rem;">x{{ item.number }}</van-row>
        <!-- 步进器 -->
        <van-row v-else style="margin-top: 3rem;">
          <!-- 如果需要异步地修改输入框的值，可以设置 async-change 属性，并在 change 事件中手动修改 value。 -->
          <van-row><van-stepper async-change @change="onChange(item)" v-model="item.number" min="1" max="10"/></van-row
        ></van-row>
      </van-col>
    </van-row>

    <!-- 底部区域 -->
    <!-- 结算栏 -->
    <div class="settlement">
      <van-row type="">
        <van-col span="6"> <input :checked="isAllchecked" type="checkbox" @click="onAllcheck" />全选 ({{ getCount.checkCount }}) </van-col>
        <van-col span="5">￥{{ getCount.totalPrice }}</van-col>
        <van-col span="12">
          <!-- 三元表达式 -->
          <button @click="onEdit">{{ isedit ? '完成' : '编辑' }}</button>
          <!-- 三元表达式 -->
          <button @click="onOverbooking">{{ isedit ? '删除(' + getCount.checkCount + ' )' : '下单' }}</button>
        </van-col>
      </van-row>
    </div>
  </div>
</template>

<script>
// jojn(',') 用任意字符串拼接数组元素，转成字符串
// ['2022','08','11'].join('-')    '2022-08-11'
import { Toast } from 'vant'
export default {
  name: 'YanxuanshangchengCart',
  data() {
    return {
      // 购物车数据
      cartIndexList: [],
      // 是否在编辑 状态
      isedit: false
    }
  },
  // 计算属性
  computed: {
    // 全选状态
    isAllchecked() {
      return this.cartIndexList.every((element, index) => {
        return element.checked
      })
    },
    // 计算价格
    getCount() {
      /*  // this.cartIndexList.reduce(callback, [initialValue])
      //     callback （执行数组中每个值的函数，包含四个参数）
      //     1、previousValue （上一次调用回调返回的值，或者是提供的初始值（initialValue））
      //     2、currentValue （数组中当前被处理的元素）
      //     3、index （当前元素在数组中的索引）
      //     4、array （调用 reduce 的数组）
      // initialValue （作为第一次调用 callback 的第一个参数。 */
      return this.cartIndexList.reduce(
        (previousValue, element, index) => {
          // 价格计算         总价格 = 价钱 * 数量
          previousValue.totalPrice += element.checked ? element.price * element.number : 0
          // 数量计算        选秀一项就是+1 不选择就是0
          previousValue.checkCount += element.checked ? 1 : 0
          // 返回结果 不返回就是 Undefined
          return previousValue
        },
        // 默认值
        { totalPrice: 0, checkCount: 0 }
      )
    }
  },

  created() {
    this.getcartIndexList()
    // 未登录账号跳转登录页操作
    if (!this.$cookie.get('username') && !this.$cookie.get('token')) {
      return this.$router.push('/login')
    }
  },

  methods: {
    // 子复选框事件
    onCheCkange(item) {
      // console.log(item)
      /*
       思路：
        只要this.cartIndexList中有一个元素吃checked=fasle，isAllchecked就是false
        数组.some((element,index)=>{}) 回调函数的返回值有一个是true，some返回true 数组.every:回调函数返回值所有都是true，才返回true */
      this.$post(this.$api.cartChecked, {
        cartIds: [item.id],
        isChecked: item.checked
      }).then(res => {
        // this.cartIndexList = res.data.data.cartList
        // console.log('修改选中', res.data.data.cartList)
      })
    },
    // 全选按钮
    onAllcheck() {
      if (!this.isAllchecked) {
        // 数组.map(回调函数) 把每个回调函数的返回值，存到新数组中返回
        // 数组.filter(回调函数) 过滤，当回调函数的返回值是true，保留element，装进新数组返回
        // console.log(cartIds)
        let cartIds = this.cartIndexList
          .filter((element, index) => {
            return !element.checked
          })
          .map((element, index) => {
            return element.id
          })
        // 发起请求
        this.$post(this.$api.cartChecked, {
          cartIds: cartIds,
          isChecked: true
        }).then(res => {
          this.cartIndexList = res.data.data.cartList
          // console.log('全选', res.data)
        })
      } else {
        // 全选状态
        let cartIds = []
        this.cartIndexList.forEach((element, index) => {
          cartIds.push(element.id)
          // 发起请求
          this.$post(this.$api.cartChecked, {
            cartIds: cartIds,
            isChecked: false
          }).then(res => {
            this.cartIndexList = res.data.data.cartList
            // console.log('取消全选', res.data)
          })
        })
      }
    },
    // 获取数据
    getcartIndexList() {
      this.$get(this.$api.cartIndex).then(result => {
        // console.log(result.data.data.cartList)
        if (result.data.errno !== 0) {
          return
        }
        // 赋值给数据
        // console.log(this.cartIndexList)
        // 只要this.cartIndexList中有一个元素吃checked=fasle，isAllchecked就是false
        // 数组.some((element,index)=>{}) 回调函数的返回值有一个是true，some返回true 数组.every:回调函数返回值所有都是true，才返回true
        this.cartIndexList = result.data.data.cartList
        console.log(this.cartIndexList)
      })
    },
    // 编辑事件
    onEdit() {
      if (this.isedit) {
        // console.log(this.cartIndexList)
        //不在编辑状态下
        // console.log('  // 不在编辑状态下')
      } else {
        // 在编辑状态下
        console.log('  // 在编辑状态下')
        // 点击编辑清空商品的全选  然后 取消编辑 不影响外面的已经选择好的
        this.cartIndexList.forEach(element => {
          element.checked = false
        })
      }
      this.isedit = !this.isedit
    },
    // 删除和下单事件
    onOverbooking() {
      if (this.isedit) {
        // 在编辑状态下  就是 删除事件
        // console.log('删除状态下')
        // 过滤出已经选择的商品的id形成一个新的数组给后台服务器删除对应的商品id
        var arrId = this.cartIndexList
          .filter(item => item.checked)
          .map(item => {
            return item.id
          })
        // console.log(arrId)
        this.$post(this.$api.cartDelete, {
          cartIds: arrId //要删除的商品对应的购物车id
        }).then(result => {
          console.log(result.data)
          if (result.data.errno == 0) {
            // 重新渲染数据
            this.getcartIndexList()
            Toast({
              message: '删除成功',
              icon: 'smile-o'
            })
          }
        })
      } else {
        // 不在编辑状态下 就是 下单事件
        console.log('下单状态下')
        // 跳转 到确定订单页面 并且通过路由传递数据
        this.$router.push({ name: 'Confirmorder', query: {} })
      }
    },
    // 异步编辑 更新 商品的 + 和 -
    onChange(item) {
      // console.log('会更新', item)
      this.$post(this.$api.cartUpdate, {
        id: item.id, //购物车Id
        productId: item.productId, //当前商品指定规格的商品ID,（不修改时传原值或0）
        goodsId: item.goodsId, //当前商品ID,
        number: item.number //商品数量,（不修改时传原值）
      }).then(result => {
        console.log(result.data)
      })
    }
  }
}
</script>

<style lang="less" scoped>
.title {
  text-align: center;
  background-color: #fff;
}
// 购物车商品
.goods-card {
  background-color: #fff;
  margin-top: 0.5rem;
  height: 8.5rem;
  .van-col {
    height: 100%;
  }
  .van-checkbox {
    margin-top: 90%;
    margin-left: 0.5rem;
  }
  .van-col:nth-child(3) {
    .van-row {
      margin-left: 1rem;
    }
  }
  img {
    width: 100%;
    height: 100%;
  }
}
// 结算栏
.settlement {
  background-color: #fff;
  width: 100%;
  height: 4rem;
  position: fixed;
  bottom: 7.5%;
  .van-col {
    margin-top: 1rem;
    height: 100%;
    margin-left: 0.5rem;
    button {
      color: #fff;
      width: 8rem;
      height: 3rem;
      border-radius: 4rem;
      border: 0.01rem transparent solid;
      background-color: #a79671;
    }
    > button:nth-child(2) {
      background-color: #9a9ba0;
    }
  }
}
</style>
